package main;

import functions.FTrim;
import interfaces.Diccionario;
import io.FlujoEntrada;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Vector;

import utiles.Cadenas;
import utiles.Colecciones;

import com.google.common.collect.Collections2;

import criterios.CRespuestaEsCorrecta;

public class DiccionarioImpl implements Diccionario {
	private Map<String, Collection<String>> diccionario;
	private String terminoActual;
	private Collection<String> acepciones;

	public DiccionarioImpl(String fichero, String delimitadores){
		this.diccionario = generarDiccionario(fichero, delimitadores);
		cambiarTermino();
	}
	
	public DiccionarioImpl(String fichero, String delimitadores, Boolean esInverso){
		this(fichero, delimitadores);
		this.diccionario = invertirDiccionario(generarDiccionario(fichero, delimitadores));
		cambiarTermino();
	}
	
	@Override
	public Map<String, Collection<String>> generarDiccionario(String fichero,
			String delimitadores) {
		
		FlujoEntrada fe = null;
		String delim1 = delimitadores.substring(0, 1);
		String delim2 = delimitadores.substring(1, 2);
		Map<String, Collection<String>> diccionario = new HashMap<String, Collection<String>>();
		
		try {
			 fe = new FlujoEntrada(fichero, delim1);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		Iterator<String> it = fe.iterator();
		while(it.hasNext()){
			String termino = it.next();
			Vector<String> acepciones = Cadenas.separaElementos(it.next().trim(), delim2);
			diccionario.put(termino, Collections2.transform(acepciones, new FTrim()));
		}
		
		return diccionario;
	}

	@Override
	public Map<String, Collection<String>> getDiccionario() {
		return diccionario;
	}

	@Override
	public String getTerminoActual() {
		return terminoActual;
	}

	@Override
	public void setTerminoActual(String termino) {
		terminoActual = termino;

	}

	@Override
	public Collection<String> getAcepciones() {
		return acepciones;
	}

	@Override
	public void setAcepciones(Collection<String> acepciones) {
		this.acepciones = acepciones; 
	}

	@Override
	public void cambiarTermino() {
		int numTerminos = getDiccionario().keySet().size();
		int random = (int)(Math.random() * (numTerminos -1)) ;
		String termino = (String)getDiccionario().keySet().toArray()[random];
		setTerminoActual(termino);
		setAcepciones(getDiccionario().get(termino));
	}

	@Override
	public Boolean respuestaCorrecta(String respuesta) {		
		return Colecciones.existe(getAcepciones(),	new CRespuestaEsCorrecta(respuesta));
	}
	
	public String toString(){
		return diccionario.toString();
	}
	
	private Map<String, Collection<String>> invertirDiccionario(Map<String, Collection<String>> diccionario){
		Map<String, Collection<String>> inverso = new HashMap<String, Collection<String>>();
		
		for (String termino : diccionario.keySet()){
			for (String acepcion  : diccionario.get(termino)){
				if (!inverso.keySet().contains(acepcion)){
					Collection<String> acepciones = new ArrayList<String>();
					acepciones.add(termino.trim());
					inverso.put(acepcion, acepciones);
				}
				else
					inverso.get(acepcion).add(termino.trim());
			}
		}
		
		return inverso;
	}
}
